package main

import (
	"fmt"
)

func main() {

	/* 声明切片 */
	declare()

}

/*
	声明切片
*/
func declare() {
	//Go 语言切片是对数组的抽象。
	//Go 数组的长度不可改变，在特定场景中这样的集合就不太适用，Go 中提供了一种灵活，功能强悍的内置类型切片("动态数组")，
	//与数组相比切片的长度是不固定的，可以追加元素，在追加时可能使切片的容量增大。

	/* 定义切面 */
	/* 声明一个未指定大小的数组来定义切片 */
	var numbers []int
	fmt.Println("长度是：", len(numbers), "， 容量是：", cap(numbers))
	s := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	fmt.Println("长度是：", len(s), "， 容量是：", cap(s))
	var s1 = s[:3]
	fmt.Println("长度是：", len(s1), "， 容量是：", cap(s1))

	/* 使用 make() 函数来创建切片 */
	var s2 = make([]int, 3)
	fmt.Println("长度是：", len(s2), "， 容量是：", cap(s2))
	var s3 = make([]int, 3, 100)
	fmt.Println("长度是：", len(s3), "， 容量是：", cap(s3))

	/* 切片截取 */
	fmt.Println("打印切片s：", s)
	fmt.Println("打印切片s[3: 5]：", s[3:5])
	fmt.Println("默认下限为 0，打印切片s[:4]：", s[:4])
	fmt.Println("默认上限为 len(s)，打印切片s[4:]：", s[4:])

	/* 切片拷贝和追加*/
	appendAndCopy()
}

/*
	切片追加
*/
func appendAndCopy() {
	//append() 和 copy() 函数
	//如果想增加切片的容量，我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来。
	//下面的代码描述了从拷贝切片的 copy 方法和向切片追加新元素的 append 方法。
	var numbers []int
	fmt.Printf("空切片：len=%d cap=%d slice=%v\n", len(numbers), cap(numbers), numbers)
	numbers = append(numbers)
	fmt.Printf("空切片再追加一个空切片，结果还是空切片：len=%d cap=%d slice=%v\n", len(numbers), cap(numbers), numbers)
	numbers = append(numbers, 1)
	fmt.Printf("添加了一个1的元素：len=%d cap=%d slice=%v\n", len(numbers), cap(numbers), numbers)
	numbers = append(numbers, 2, 3, 4, 5)
	fmt.Printf("同时添加多个元素：len=%d cap=%d slice=%v\n", len(numbers), cap(numbers), numbers)

	/* 创建切片 numbers1 是之前切片的两倍容量*/
	numbers1 := make([]int, len(numbers), (cap(numbers))*2)
	/* 拷贝 numbers 的内容到 numbers1 */
	copy(numbers1, numbers)
	fmt.Printf("拷贝 numbers 的内容到 numbers1 ：len=%d cap=%d slice=%v\n", len(numbers1), cap(numbers1), numbers1)
}

func printSlice(x []int) {
	fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
